home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
hamradio
/
sgp4_pl2.zip
/
SGP4-PLB.ITF
< prev
next >
Wrap
Text File
|
1992-10-01
|
39KB
|
826 lines
Documentation for
NORAD SGP4/SDP4 Units
Interface Specifications
Developed by
Dr TS Kelso
Version 2.50
1992 October 01
Copyright (C) 1992. All rights reserved.
INTRODUCTION
The following document is intended to provide complete documentation for the
interface section of the units provided in this package. Each unit will be
presented, in alphabetical order, and the INTERFACE section is reproduced,
showing the exact nature of each call. Following this information will be a
description of the intended use of each variable and procedure.
** UNIT MINMAX -- VERSION 1.02 ***********************************************
Function IMin(arg1,arg2 : integer) : integer;
Function IMax(arg1,arg2 : integer) : integer;
Function RMin(arg1,arg2 : real) : real;
Function RMax(arg1,arg2 : real) : real;
Function DMin(arg1,arg2 : double) : double;
Function DMax(arg1,arg2 : double) : double;
These functions are used to provide integer, real, and double minimum and
maximum calculations used in the libraries.
** UNIT SGP4SDP4 -- VERSION 1.50 *********************************************
Uses Support,
SGP_Init,
SGP_Math,SGP_Time;
Procedure SGP(time : double;
var pos,vel : vector);
Procedure SGP4(tsince : double;
var iflag : integer;
var pos,vel : vector);
Procedure SDP4(tsince : double;
var iflag : integer;
var pos,vel : vector);
This unit contains the Pascal implementation of the SGP4 and SDP4 orbital
models. Two methods of interfacing are available. The first method is to
access the individual routines exactly as described in Project Spacetrack
Report Number 3 (Procedures SGP4 and SDP4). This method requires the user to
calculate the time (in minutes) since each satellite element set epoch and
determine the appropriate model to use. The variable {iflag} is used to keep
track of initialization status and is set within these routines and within
Convert_Satellite_Data (Unit SGP_CONV). This method is *NOT* recommended.
The second method is to access the orbital models via a call to SGP. Here the
user is only required to pass a time (Julian Date) for the calculation and the
satellite ECI position and velocity are returned. Determination of the
appropriate orbital model is transparent to the user. The only requirement is
that a call to Convert_Satellite_Data be made each time a new satellite is
selected before calling SGP. Routines for calculating Julian Dates are
included in Unit SGP_TIME.
** UNIT SGP_CONV -- VERSION 1.00 *********************************************
Uses SGP_Math;
Procedure Convert_Satellite_Data(arg : integer);
Procedure Convert_Sat_State(var pos,vel : vector);
The first procedure is used to extract the data in a given two-line element
set to the variables expected by UNIT SGP4SDP4. The data structures
containing the two-line element sets is described in UNIT SGP_INIT. In
addition, a determination as to whether the near-earth (SGP4) or deep-space
(SDP4) model should be used is made within this unit. These variables are
passed between SGP4SDP4 and SGP_CONV using UNIT SGP_INTF. This unit
(SGP_INTF) should NOT be included in the main program unless absolutely
necessary to avoid unintentional changes to these critical variables. Two
additional variables, {catnr} and {elset}, are provided to identify the
satellite element set. Finally, the variable {epoch} is globally available to
determine the epoch of the element set.
Convert_Sat_State is used to convert the native units provided by SGP4/SDP4
(position in earth radii, velocity in earth radii/minute) to standard metric
units (kilometers and kilometers/sec).
** UNIT SGP_IN -- VERSION 2.00 ***********************************************
(** This unit contains machine-specific code **)
Uses SGP_Math,SGP_Init,Support;
const
data_type : byte = 3;
var
fsat,fobs : text;
Procedure Select_Time(message : string;
xpos,ypos : byte;
var default : time_set;
precision : byte);
Procedure Select_Time_Interval(message : string;
xpos,ypos : byte;
var default : time_set;
precision : byte);
Function Checksum_Good(line : line_data) : boolean;
Function Good_Elements(lines : two_line) : boolean;
Procedure Input_Satellite(index : word);
Function Input_Satellite_Data(fn : string) : word;
Procedure Select_Satellites(title : string;
x,y,w,h : byte;
number : word);
Procedure Input_Observer(var geodetic : vector);
This unit is one of two units which contain machine-specific code; this
limitation will probably be removed in the future, moving all machine-specific
code to UNIT SUPPORT.
The constant {data_type} is preset to 3 and is used to specify the format of
the two-line orbital data file. A value of 2 indicates that the satellite
data files contain *only* two-line data; a value of 3 indicates that each two-
line element set is preceded by a 22-character satellite name. These data are
read into data structures as described in UNIT SGP_INIT. The value of
{data_type} can be changed in the main program and, if necessary, should be
done within the program initialization block.
The variables {fsat} and {fobs} are predefined text files to be assigned to
the satellite and observer files, respectively. Routines used in this unit
expect to use these file handles.
The first two procedures, Select_Time and Select_Time_Interval, are provided
to make it easy to input start/stop times and time intervals for performing
calculations. Each procedure will put a window on the screen with the title
specified by {message} at the location ({xpos},{ypos}). A default time set is
passed to initialize the time; the structure of this variable is set forth in
UNIT SUPPORT. The variable {default} may be initialized manually or by a call
to Get_Current_Time (for Select_Time) or Zero_Time (for Select_Time_Interval);
each of these procedures is also in UNIT SUPPORT. The variable {precision} is
used to indicate the precision of the data to be selected. Precision ranges
from years down to hundredths of a second. A precision of 7 indicates that
all time units are to be input; a precision of 5 would omit inputting seconds
and hundredths of seconds. All values beyond the specified precision are set
to zero, regardless of any other user action.
The next two functions are used to determine whether a given two-line element
set is "good" -- at least in the sense that it passes the modulo-10 checksum
on each line and that all the numbers appear to be in the proper fields. A
simple call passing the two-line element set {lines} to Good_Elements returns
TRUE if the data passes these tests. The function Checksum_Good can be used
to test the modulo-10 checksum for a single line of a two-line element set.
These functions are not used explicitly during element set input as it is
assumed that the user has already done so (all data that I post has already
been subjected to these tests). In fact, the program PASSUPDT, which is
available on this system for updating files of two-line element sets from a
master file, does this checking for you. However, if you are unsure of the
quality of your data, it is STRONGLY RECOMMENDED that you develop your own
preprocessor using these functions to test your data.
The procedure Input_Satellite is used to read in individual two-line element
sets. The index indicates its placement within the data array. This call
assumes that {fsat} has already been ASSIGNed and initialized. Typically,
this call is made from the function Input_Satellite_Data which initializes
{fsat} and reads an entire file into memory from the file {fn}; the output of
this function is the number of satellites in {fn}. However, due to memory
limitations, some files will be too large to read into memory. In these
cases, Input_Satellite should be used to sequentially read and process
individual element sets; each element set could be read into {index}=1 and
processed before proceeding.
In cases where all the orbital data can be read into memory and {data_type}=3,
the procedure Select_Satellites can be used to tag satellites for calculations
later in the program using the array {selected}. Initially, no satellites are
selected. A call to this procedure will place a window on the screen with the
upper-left corner at ({x},{y}) and having a width {w} and maximum height {h}
(the height ranges from 1 to the minimum of {h} and the number of satellites).
A {title} is also put on the window. The final parameter in this call is the
number of satellites available. Selection is achieved by moving with the
up/down cursor keys to the appropriate satellite and toggling with the space
bar (an asterisk marks an item as being selected); data scrolls in the window
as necessary. Toggling advances to the next item in the list, making it
easier to quickly mark items. The 'A' key toggles All items (negates their
current status). Once the desired items are selected, the [ENTER] key
completes the process. Within the main program, items can be tested for
selection with a statement such as: if selected[index] then ...
The final procedure for this unit is Input_Observer and it works somewhat like
Input_Satellite except that the data is read into a {geodetic} four-vector
where {geodetic}[1] is North latitude, {geodetic}[2] is East longitude (that
means that West longitudes are negative), and {geodetic}[3] is altitude above
mean sea level (AMSL). Input is expected from the file {fobs} in units of
degrees and meters but is immediately converted to radians and kilometers for
use within these units. Each observer entry in {fobs} consists of a single
line beginning with a 25-character site name (passed as {obs_name}); it is
expected that this name has a three-character short name (or number), two
spaces, followed by a long name. The short name is used within UNIT SGP_OUT
for topocentric output. The remaining three numbers on this line are free-
field format, beginning on or after character 26.
** UNIT SGP_INIT -- VERSION 1.10 *********************************************
const
max_sats = 250;
type
line_data = string[69];
two_line = array [1..2] of line_data;
var
visible : boolean;
epoch : double;
catnr,elset : string;
obs_name : string[25];
selected : array [1..max_sats] of boolean;
sat_name : array [1..max_sats] of string[22];
sat_data : array [1..max_sats] of two_line;
data_drive,data_dir,
work_drive,work_dir : string;
Procedure Program_Initialize(program_name : string);
This unit is used to initialize most of the data structures specific to the
SGP4 family of units. The constant {max_sats} sets the limit (imposed by
system memory constraints) on the maximum number of satellites available.
This constant affects the storage allocation for two-line element sets in
the array {sat_data}, satellite names in the array {sat_name}, and the array
of selected satellites in {selected}. Note that type {two_line} is a two-
element string of 69-character lines.
The first variable provided is a boolean variable {visible} which is set
when making calls to determine topocentric position; if the satellite is
visible to the observer, {visible} is set true, otherwise it is set false.
Checks of this variable make sense only in this context. Eventually, this
variable will also be used in determining other visibility conditions.
The next three variables pertain to the current two-line element set (the last
one processed through Convert_Satellite_Data). The variables {catnr} and
{elset} are read from the appropriate field of Line 1 and serve to identify
the data. The variable {epoch} marks the epoch time (in two-line format) of
that element set.
The final four variables are determined in the procedure Program_Initialize.
They are used to specify the location of data files ({fsat} and {fobs} files)
and output files. Having separate locations for these two groups makes
development and testing easier (in my opinion) and allows for standard
locations to facilitate integration with other programs (it doesn't make sense
to have various versions of two-line element set files scattered all over your
hard disk). These values are specified in the configuration file
{program_name}.CFG (if it exists; if not, everything defaults to the working
disk and directory). For example, in the program TRAKSTAR, there would be a
file TRAKSTAR.CFG which might look like:
d:
\data\
e:
\work\
If this program were located in C:\SGP4 and the data was in C:\SGP4\DATA and
work files were to go to C:\SGP4\WORK, the configuration file might look like:
c:
\sgp4\data\
c:
\sgp4\work\
Note that each directory ends with a trailing \ (and should have no blanks).
If you wish to run from the default drive (useful when using removable
cartridges and moving between systems), you might change the above to:
\sgp4\data\
\sgp4\work\
To specify directories which are below the working directory, you could also
use:
data\
work\
The call to Program_Initialize will read {program_name}.CFG to determine this
information (if it exists) and will also read {program_name}.HDR (if it
exists) to place one page of information on the screen to identify the
program. It is strongly recommended that these parameters be used in your
programs to facilitate traceability and portability.
A call to Program_End is strongly recommended to reset the terminal after
program execution. Currently, this procedure positions the cursor to the
bottom of the screen and makes sure it is on.
** UNIT SGP_INTF -- VERSION 1.02 *********************************************
const
ae = 1;
tothrd = 2/3;
xkmper = 6378.135; {Earth equatorial radius - kilometers (WGS '72)}
f = 1/298.26; {Earth flattening (WGS '72)}
ge = 398600.8; {Earth gravitational constant (WGS '72)}
J2 = 1.0826158E-3; {J2 harmonic (WGS '72)}
J3 = -2.53881E-6; {J3 harmonic (WGS '72)}
J4 = -1.65597E-6; {J4 harmonic (WGS '72)}
ck2 = J2/2;
ck4 = -3*J4/8;
xj3 = J3;
qo = ae + 120/xkmper;
s = ae + 78/xkmper;
e6a = 1E-6;
dpinit = 1; {Deep-space initialization code}
dpsec = 2; {Deep-space secular code}
dpper = 3; {Deep-space periodic code}
var
iflag,ideep : integer;
xmo,xnodeo,omegao,eo,xincl,
xno,xndt2o,xndd6o,bstar,
julian_epoch,xke : double;
This unit defines the constants and variables used internal to SGP4SDP4. Note
that this version still uses WGS '72 values (while the impact of switching to
WGS '84 is assessed). It is STRONGLY recommended that this unit NOT be
included in the main program. All determinations using these constants (such
as position of an observer on the earth's surface in the ECI system) should be
performed through the appropriate call. Also, note that {iflag} and {ideep}
are unavailable to the main program under this recommendation, forcing the use
of the procedure SGP to access the NORAD orbital models.
** UNIT SGP_MATH -- VERSION 1.30 *********************************************
type
vector = array [1..4] of double;
const
twopi = 2 * pi;
zero : vector = (0,0,0,0);
Function Sign(arg : double) : shortint;
Function Cube(arg : double) : double;
Function Power(arg,pwr : double) : double;
Function Radians(arg : double) : double;
Function Degrees(arg : double) : double;
Function Tan(arg : double) : double;
Function ArcSin(arg : double) : double;
Function ArcCos(arg : double) : double;
Function Modulus(arg1,arg2 : double) : double;
Function Fmod2p(arg : double) : double;
Function AcTan(sinx,cosx : double) : double;
Function Dot(v1,v2 : vector) : double;
Procedure Magnitude(var v : vector);
Procedure Cross(v1,v2 : vector; var v3 : vector);
This unit first defines the the type {vector} is as a four-element array (or
four-vector) consisting (typically) of x, y, and z position and a vector
magnitude. These vectors are also used for storing other types of information
(as will be seen in UNIT SGP_OBS). Next, the constant {twopi} is defined as
appropriate for Turbo Pascal Version 6.0. Note that earlier versions of Turbo
Pascal will NOT allow constant definitions of this form. The definition of a
zero vector has been added for this release.
The remaining routines are defined below.
Function Sign(arg : double) : shortint;
Output is the sign (-1, 0, +1) of {arg}.
Function Cube(arg : double) : double;
Output is {arg} to the third power.
Function Power(arg,pwr : double) : double;
Output is {arg} to the {pwr} power. This is a more general-purpose
function, but is restricted to positive values of {arg}. An error
message is reported if {arg} violates this restriction.
Function Radians(arg : double) : double;
Output is an angle in radians where {arg} was input in degrees.
Function Degrees(arg : double) : double;
Output is an angle is degrees where {arg} was input in radians.
Function Tan(arg : double) : double;
Output is the tangent of {arg}.
Function ArcSin(arg : double) : double;
Output is the arcsine of {arg} in radians. Values range between -pi and
+pi.
Function ArcCos(arg : double) : double;
Output is the arccosine of {arg} in radians. Values range between 0 and
2*pi.
Function Modulus(arg1,arg2 : double) : double;
Output is the remainder after {arg1} is divided by {arg2}. This routine
is useful for keeping angles between 0 and 2*pi (or 0 and 360 degrees).
Function Fmod2p(arg : double) : double;
This function is a specific implementation of Modulus where {arg2} equals
2*pi. Used explicitly within SGP4SDP4.
Function AcTan(sinx,cosx : double) : double;
Output is the arctangent of {sinx}/{cosx} in radians. Used explicitly
within SGP4SDP4. The advantage of this function over ArcTan is that it
returns the correct quadrant of the angle.
Function Dot(v1,v2 : vector) : double;
Output is the vector dot product of {v1} and {v2}.
Procedure Magnitude(var v : vector);
This procedure calculates the magnitude of vector {v} using components 1,
2, and 3, storing the result in component 4.
Procedure Cross(v1,v2 : vector; var v3 : vector);
Returns vector {v3} which is the vector cross product of {v1} and {v2}.
** UNIT SGP_OBS -- VERSION 1.40 **********************************************
Uses SGP_Math;
Procedure Calculate_User_PosVel(var geodetic : vector;
time : double;
var obs_pos,obs_vel : vector);
Procedure Calculate_LatLonAlt(pos : vector;
time : double;
var geodetic : vector);
Procedure Calculate_Obs(pos,vel,geodetic : vector;
time : double;
var obs_set : vector);
Procedure Calculate_RADec(pos,vel,geodetic : vector;
time : double;
var obs_set : vector);
These procedures are used to provide observer-specific coordinate
transformations of the output of the NORAD orbital models.
Procedure Calculate_User_PosVel passes the user's geodetic position and the
time of interest and returns the ECI position and velocity of the observer.
The format of {geodetic} is as explained in UNIT SGP_IN. The velocity
calculation assumes the geodetic position is stationary relative to the
earth's surface. This routine is made available to the user, although the
exact nature of its application is uncertain. This procedure is used,
however, as the basis for Calculate_Obs and Calculate_RADec, to be explained
later.
Procedure Calculate_LatLonAlt will calculate the {geodetic} position of an
object given its ECI position {pos} and {time}. It is intended to be used to
determine the ground track of a satellite. The calculations assume the earth
to be an oblate spheroid as defined in WGS '72.
The procedures Calculate_Obs and Calculate_RADec calculate the *topocentric*
coordinates of the object with ECI position, {pos}, and velocity, {vel}, from
location {geodetic} at {time}. The {obs_set} returned for Calculate_Obs
consists of azimuth, elevation, range, and range rate (in that order) with
units of radians, radians, kilometers, and kilometers/second, respectively.
The WGS '72 geoid is used and the effect of atmospheric refraction (under
standard temperature and pressure) is incorporated into the elevation
calculation; the effect on range and range rate has not yet been quantified.
The {obs_set} for Calculate_RADec consists of right ascension and declination
(in that order) in radians. Again, calculations are based on *topocentric*
position using the WGS '72 geoid and incorporating atmospheric refraction.
** UNIT SGP_OUT -- VERSION 1.50 **********************************************
Uses SGP_Math;
const
day_date : boolean = true;
full_time : boolean = true;
N_E_W_S : boolean = false;
D_M_S : boolean = false;
time_res : byte = 2;
angle_res : byte = 4;
dist_res : byte = 3;
var
fout : text;
Procedure Output_Time(time : double);
Procedure Output_ECI(time : double;
pos,vel : vector);
Procedure Output_Angle(angle : double;
width,dec : byte;
degrees : boolean);
Procedure Output_LatLonAlt(time : double;
geodetic : vector);
Procedure Output_Obs(time : double;
obs : vector);
Procedure Output_RADec(time : double;
obs : vector);
This unit begins with a set of constants used as formatting parameters. The
intention here is to set these values for consistency in the output and not
clutter output calls with formatting information. While the default values
are set above, it is easy to change these values either globally or locally.
For example, the user may decide to change these values in the program
initialization step. Or, these values could be set prior to making calls to
routines within UNIT SGP_OUT.
The constant {day_date} allows for selection of output time as day/date (if
true) or as a Julian Date (easier to read into other programs).
The constant {full_time} allows the selection of times with colons between the
hours and minutes and between the minutes and seconds (i.e., HH:MM:SS), if set
true.
The constant {N_E_W_S} is used with outputs of latitude and longitude to
specify an output with North/South or East/West (if true) rather than plus or
minus values.
The constant {D_M_S} allows for angular output in degrees, minutes, and
seconds (if true) rather than decimal degrees.
The final three constants are used to set the precision of output for time,
angle, and distance variables, respectively. The default for {time_res} of 2
indicates output to hundredths of a second. The default for {angle_res} of 4
indicates output to four decimal places (if D_M_S = false) or arcseconds (if
D_M_S = true); outputs in degrees, minutes, and seconds are rounded to tens of
arcminutes, arcminutes, tens of arcseconds, and seconds for values of 1, 2, 3,
and 4, respectively. The default for {dist_res} of 3 indicates a precision to
three decimal places in distances (i.e., meters) and six decimal places in
velocities (i.e., millimeters/second).
The variable {fout} is a pre-defined variable to specify the output file.
The procedure Output_Time is used to output either the calendar date and time
of day or Julian Date of {time} to {fout}.
The procedure Output_ECI outputs ECI position {pos} (in kilometers) and
velocity {vel} (in kilometers/second) vectors along with the time.
The procedure Output_Angle outputs an angle {angle} in a field of width
{width} with {dec} decimal places. The variable {degrees} is used when
{D_M_S} is true to specify whether the angular output is degrees or hours.
The procedure Output_LatLonAlt output the time, latitude (in degrees),
longitude (in degrees), and altitude (in kilometers) of an object.
The procedure Output_Obs outputs the time, azimuth (in degrees), elevation (in
degrees), range (in kilometers), and range rate (in kilometers/second with
negative values approaching the observer).
The procedure Output_RADec outputs the time, right ascension (in hours), and
declination (in degrees).
Output_ECI and Output_LatLonAlt now write ECL at the end of each line if the
satellite is in earth umbral eclipse.
Output_Obs and Output_RADec now output a blank line at the completion of a
pass.
** UNIT SGP_TIME -- VERSION 1.50 *********************************************
Uses SGP_Math;
type
clock_time = string[12];
date = string[11];
const
xmnpda = 1440.0; {Minutes per day}
secday = 86400.0; {Seconds per day}
omega_E = 1.00273790934; {Earth rotations per sidereal day (non-constant)}
omega_ER = omega_E*twopi; {Earth rotation, radians per sidereal day}
var
ds50 : double;
Function Julian_Date_of_Year(year : double) : double;
Function Julian_Date_of_Epoch(epoch : double) : double;
Function Epoch_Time(jd : double) : double;
Function DOY(yr,mo,dy : word) : word;
Function Fraction_of_Day(hr,mi,se,hu : word) : double;
Function Calendar_Date(jd : double) : date;
Function Time_of_Day(jd : double;
full : boolean;
res : byte) : clock_time;
Function ThetaG(epoch : double) : double;
Function ThetaG_JD(jd : double) : double;
Function Delta_ET(year : double) : double;
This unit contains all the routines to perform time conversions.
The function Julian_Date_of_Year calculates the Julian Date of Day 0.0 of
{year}. This function is used to calculate the Julian Date of any date by
using Julian_Date_of_Year, DOY, and Fraction_of_Day.
The function Julian_Date_of_Epoch returns the Julian Date of an epoch
specified in the format used in the NORAD two-line element sets.
The function DOY calculates the day of the year for the specified date. The
calculation uses the rules for the Gregorian calendar and is valid from the
inception of that calendar system.
Fraction_of_Day calculates the fraction of a day passed at the specified input
time.
The function Calendar_Date converts a Julian Date to a string of the form
"yyyy Mon dd". It is typically used as the major output time format.
Time_of_Day takes a Julian Date and calculates the clock time portion of that
date. The variable {full} is set true if it is desired to place colons
between hours and minutes and minutes and seconds. The variable {res} is used
to determine the number of decimal places after the seconds in the output;
zero gives a resolution of seconds, one gives a resolution of tenths of
seconds, etc. The variable {res} can take on values between 0 and 3.
The function ThetaG calculates the Greenwich Mean Sidereal Time for an epoch
specified in the format used in the NORAD two-line element sets. The function
ThetaG_JD provides the same calculation except that it is based on an input in
the form of a Julian Date.
The function Delta_ET has been added to allow calculations on the position of
the sun. It provides the difference between UT (approximately the same as UTC)
and ET (now referred to as TDT). This function is based on a least squares fit
of data from 1950 to 1991 and will need to be updated periodically.
** UNIT SOLAR -- VERSION 1.20 ************************************************
Uses SGP_Math;
const
eclipsed : boolean = false;
show_vis : boolean = false;
var
civil,
nautical,
astronomical : double; {Twilight elevations}
solar_pos : vector;
Procedure Calculate_Solar_Position(time : double;
var solar_vector : vector);
Function Depth_of_Eclipse(time : double;
r1 : vector) : double;
The variable {eclipsed} is provided for use with the Function Depth_of_Eclipse
to reflect whether a satellite is in earth umbral eclipse. The constant
{show_vis} is used to indicate whether information should be output for all
passes or only visible passes (i.e., satellite above the observer's horizon,
not in earth umbral eclipse, and the sun below the appropriate threshold for
skies to be dark at the observer's location).
The variables {civil}, {nautical}, and {astronomical} are initialized to the
thresholds for solar elevation defining the corresponding twilights. These
are defined to occur at 6, 12, and 18 degrees below the horizon, respectively.
The variable {solar_pos} is provided to track the position of the sun as
calculated in Depth_of_Eclipse, thus avoiding an additional call to
Calculate_Solar_Position.
The procedure Calculate_Solar_Position calculates the position of the sun in
the ECI coordinate system at the designated time (UTC). The procedure makes
an adjustment for the difference between UT and TDT by calling Delta_ET in
Unit SGP_TIME. The variable {solar_vector} returns the ECI position in
kilometers and calculates the distance to the sun.
The function Depth_of_Eclipse calculates the distance an object at position
{r1} at {time} is into the cone enclosing both the earth and the sun. On the
side of the earth away from the sun, this cone defines the earth's umbral
shadow. This distance is determined by first finding the perpendicular
distance of the object from the line going through the centers of both the
earth and the sun and then calculating the distance of the edge of the cone
from this same line along the perpendicular. The depth into eclipse is defined
as the difference of these two distances. Positive values reflect distances
outside the eclipse zone. Because the object can be within the cone on either
side of the earth, the variable {eclipsed} is set true if the object is within
the cone on the side of the earth opposite of the sun.
** UNIT SUPPORT -- VERSION 1.81 **********************************************
const {IBM PC screen codes}
BS = ^H; {Backspace}
CR = ^M; {Carriage Return}
CRLF = ^M^J; {Carriage Return/Line Feed}
BELL = ^G; {Terminal Bell}
ESC = ^[; {Escape}
DEL = #$7F; {Delete}
Up = #72; {Up Cursor}
Dn = #80; {Down Cursor}
Rt = #77; {Right Cursor}
Lt = #75; {Left Cursor}
Home = #71; {Home Key}
Endd = #79; {End Key}
PgUp = #73; {Page Up}
PgDn = #81; {Page Down}
C_Lt = #115; {Control-Left Cursor}
C_Rt = #116; {Control-Right Cursor}
C_PgUp = #132; {Control-Page Up}
C_PgDn = #118; {Control-Page Down}
UpDown = #24#25; {Up/Down Arrows}
Cursors = #24#25#26#27; {Up/Down/Left/Right Arrows}
SFrame : string = '┌─┐│└┘┴┬├┼┤'; {Single-Line Frame Characters}
DFrame : string = '╔═╗║╚╝╩╦╠╬╣'; {Double-Line Frame Characters}
MFrame : string = '╡╞╕╛╘╒'; {Mixed-Line Frame Characters}
type
options = array [0..10] of string;
time_set = record
yr,mo,dy,hr,mi,se,hu : word;
end; {record}
Procedure Cursor_On;
Procedure Cursor_Off;
Procedure Save_Cursor;
Procedure Restore_Cursor;
Procedure ReverseVideo;
Procedure NormalVideo;
Procedure BoldVideo;
Procedure FrameWindow(x,y,w,h,color : byte; title : string);
Procedure MakeWindow(x,y,w,h,color : byte; title : string);
Procedure ClearWindow(x,y,w,h : byte);
Procedure Show_Status_Line(title : string);
Procedure Show_Instructions(title : string);
Procedure Clear_Status_Line;
Procedure Report_Error(x,y : byte; title : string);
Procedure Beep;
Procedure Buzz;
Procedure Mark_Time;
Procedure Zero_Time(var time : time_set);
Procedure Get_Current_Time(var time : time_set);
Function Yes : boolean;
Function TwoDigit(arg : integer) : string;
Function ThreeDigit(arg : integer) : string;
Procedure Convert_Blanks(var field : string);
Function Integer_Value(buffer : string;
start,length : integer) : integer;
Function Real_Value(buffer : string;
start,length : integer) : double;
Function File_Exists(filename : string) : boolean;
Function Select_File(title,pattern,default : string; x,y,w,h : byte) : string;
Function Select_Option(menu : options; number,x,y,w,h : byte) : byte;
This unit is considerably different from the other units in this library and
is intended to be a general support library for a specific hardware
implementation, in this case the IBM PC compatible family of microcomputers
running Microsoft DOS. Eventually, *ALL* machine-specific code will be put in
this unit to enhance portability, meaning that only these routines will have
to be changed to port it to another machine. I have decided not to delay the
release of the package to achieve this goal since there is no widely available
standard implementation of Pascal to necessitate such changes. However, when
these units are converted to C, all machine-specific routines will be limited
to this unit.
The unit begins with a set of constants which define the specifics of various
keys and characters on IBM PCs; their definitions are commented above.
The two types defined are an array of {options} which are used with the
function Select_Option and {time_set} which is a record containing the year,
month, day, hour, minute, second, and hundredth of seconds.
The remaining routines are described below.
Procedure Cursor_On;
Turns on a block cursor on the screen at the current cursor location.
Procedure Cursor_Off;
Hides the cursor from view.
Procedure Save_Cursor;
Saves the current position of the cursor.
Procedure Restore_Cursor;
Restores the cursor location to the last saved location.
Procedure ReverseVideo;
Changes the text attributes to reverse video (black on white).
Procedure NormalVideo;
Changes the text attributes to normal_video (white on black).
Procedure BoldVideo;
Changes the text attributes to bold (yellow on black).
Procedure FrameWindow(x,y,w,h,color : byte; title : string);
Puts a frame around a window (and is usually called by MakeWindow).
Procedure MakeWindow(x,y,w,h,color : byte; title : string);
Makes a window, located at ({x},{y}) with width {w} and height {h} in
color {color}. A {title} is put on the window.
Procedure ClearWindow(x,y,w,h : byte);
ClearWindow simply clears a window from the display. The code does not,
at this time, allow restoration of underlying screen text.
Procedure Show_Status_Line(title : string);
Shows status on the left side of the last line of the display. Usually
used in support of providing brief instructions during input.
Procedure Show_Instructions(title : string);
Similar to Show_Status_Line except providing right-justified output on
the last line of the display.
Procedure Clear_Status_Line;
Clears the last line of the display.
Procedure Report_Error(x,y : byte; title : string);
Reports the error specified by {title} in BoldVideo at the position
({x},{y}) and then exits the program.
Procedure Beep;
Sounds a high-pitched tone to draw attention.
Procedure Buzz;
Sounds a lower-pitched tone to indicate an error condition.
Procedure Mark_Time;
A rotating cursor to serve as a visual indication that the machine is
still operating during time-intensive operations.
Procedure Zero_Time(var time : time_set);
Places zeros in all element of {time}. Useful in initializing in
preparation for a call to Select_Time_Interval.
Procedure Get_Current_Time(var time : time_set);
Reads the current system time into variable {time}. Useful for
initializing Select_Time.
Function Yes : boolean;
A function which waits for the input of a Y or N in response to a
question. The words Yes or No are printed in response to the appropriate
input and Yes is set true if a positive response is received. For
example,
Write('Are you ready? ');
if Yes then Do_Ready else Do_Not_Ready;
Function TwoDigit(arg : integer) : string;
Converts an integer to a two-digit string with leading zeros.
Function ThreeDigit(arg : integer) : string;
Converts an integer to a three-digit string with leading zeros.
Procedure Convert_Blanks(var field : string);
Used with the next two functions to convert leading spaces to zeros to
facilitate text conversion to integers or reals.
Function Integer_Value(buffer : string;
start,length : integer) : integer;
Takes the segment of {buffer} beginning at {start} and having length
{length} and converts it to an integer number.
Function Real_Value(buffer : string;
start,length : integer) : double;
Takes the segment of {buffer} beginning at {start} and having length
{length} and converts it to a double precision real number.
Function File_Exists(filename : string) : boolean;
Checks to see if {filename} exists.
Function Select_File(title,pattern,default : string; x,y,w,h : byte) : string;
Allows for easy selection of input files. Select_File places a window on
the screen with upper-left corner at location ({x},{y}) and having width
{w} and maximum height of {h}. The window is labeled with {title} and
{pattern} specifies the pattern of files to look for; {default} is the
default pattern (this filename is highlighted, if present). Select_File
returns the filename selected.
Function Select_Option(menu : options; number,x,y,w,h : byte) : byte;
Allows for the easy selection of an option from a menu {menu}. The
values of {x}, {y}, {w}, and {h} are the same as for Select_File;
{number} indicates the total number of options available. Select_Option
returns the option number selected.